﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Hash
{
    public class HashHelper<T>
    {
        private static SortedDictionary<int, T> _hash = new SortedDictionary<int, T>();
        //由多少个桶组成环
        private static List<T> Nodes = null;
        //每个节点有多少个虚拟节点
        private static int? VirtualNodePerNode = null;
        private const int HASH_CONST = int.MaxValue;
        public void Init(List<T> Nodes,int? VirtualNodePerNode=null)
        {
            if(Nodes == null)
            {
                throw new Exception("未初始化数据!");
            }
            HashHelper<T>.Nodes = Nodes;
            if (VirtualNodePerNode == null)
            {
                HashHelper<T>.VirtualNodePerNode = 0;
            }
            else
            {
                HashHelper<T>.VirtualNodePerNode = VirtualNodePerNode;
            }
            InitHash();
        }

        private void InitHash()
        {
            Nodes.ForEach(t =>
            {
                int result = (t.GetHashCode()& int.MaxValue) % HASH_CONST;
                _hash.Add(result, t);
                for(int i = 0; i < VirtualNodePerNode; i++)
                {
                    int VirtualResult = ($"{t}#{i}".GetHashCode()& int.MaxValue) % HASH_CONST;
                    _hash.Add(VirtualResult, t);
                }
            });
        }

        public T GetNode(string key)
        {
            int reuslt = (key.GetHashCode()&int.MaxValue) % HASH_CONST;
            //取小于hash结果的最大key
            int dickey = _hash.Keys.Where(x => x < reuslt).Max();
            List<int> keylist = _hash.Keys.ToList();
            //如果在最后一个节点之后，就去找第一个节点
            int index = keylist.IndexOf(dickey);
            if (index == _hash.Keys.Count() - 1)
            {
                return _hash[_hash.Keys.FirstOrDefault()];
            }
            else
            {
                return _hash[keylist[index + 1]];
            }
        }


    }
}
